home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 001 / fastplot.arc / FASTPLOT.ASM
Assembly Source File  |  1988-09-14  |  20KB  |  699 lines

  1. TITLE FASTPLOT.ASM
  2. COMMENT *
  3. This program reads both ASCII and binary files from any disk drive of
  4. any IBM/PC/XT or clone. It sends the file contents to the 'COM' port
  5. while maintaining several different handshake protocols. The most common
  6. protocol uses clear to send (CTS, pin 4 of the DB25 connector) to signal
  7. the host when to start/stop sending data. The next most common protocol
  8. uses data set ready (DSR, pin 20 of the DB25 connector) to signal the
  9. host in the same manner. The last method uses X-ON/X-OFF protocol in which
  10. the device sends the host a byte (^S or ^Q) which is used to start/stop
  11. the data flow from the host. All three protocols are supported in this
  12. program. *
  13. ;
  14. ; Created    30-DEC-86    Richard B. Johnson
  15. ; Modification record:
  16. ; 04-JAN-86    Added multiple port routines to address 5 COM ports.    :RBJ
  17. ; 06-JAN-86    Added routine to check for invalid COM port. Checks to
  18. ;        see if the required UART (8250) is present. For speed,
  19. ;        this process 'talks' directly to the UART so it's type
  20. ;        must be known for the routines to work.            :RBJ
  21. ;
  22. CR    EQU    0DH
  23. LF    EQU    0AH
  24. BEL    EQU    07H
  25. COL_LEN    EQU    60        ;100 PERCENT OF THE COLUMN
  26. DTA    EQU    80H        ;DEFAULT DATA TRANSFER AREA
  27. MS_DOS    EQU    21H        ;SYSTEM CALLS
  28. KBD    EQU    16H        ;KEYBOARD ROM VECTOR
  29. VID_ROM    EQU    10H        ;VIDEO ROM VECTOR
  30. X_ON    EQU    'Q'-64        ;PROTOCOL BYTES
  31. X_OFF    EQU    'S'-64
  32. CTL_C    EQU    'C'-64
  33. ;         8250 UART EQUATES
  34. LSTAT    EQU    5        ;OFFSET TO LINE STATUS REGISTER
  35. MSTAT    EQU    6        ;OFFSET TO MODEM STATUS REGISTER
  36. CTS    EQU    00010000B    ;CLEAR TO SEND
  37. DSR    EQU    00100000B    ;DATA SET READY
  38. DR    EQU    00000001B    ;DATA READY
  39. THRE    EQU    00100000B    ;TRANSMITTER HOLDING REGISTER READY
  40. BIOS_DATA_SEG    EQU    40H    ;ROM DATA SEGMENT
  41. ;
  42. FILE_BUF    STRUC        ;DTA STRUCTURE AFTER A 'FIND FIRST' CALL
  43. RES    DB    21 DUP (?)    ;RESERVED
  44. ATTR    DB    ?        ;FILE ATTRIBUTE FOUND
  45. TIME    DW    ?        ;TIME FILE CREATED
  46. DATE    DW    ?        ;DATE FILE CREATED
  47. SIZEL    DW    ?        ;LOW WORD OF THE FILE SIZE
  48. SIZEH    DW    ?        ;HIGH WORD OF THE FILE SIZE
  49. NAMEF    DB    ?        ;FOUND FILENAME
  50. FILE_BUF    ENDS
  51. ;
  52. IF1
  53.     %OUT    [PASS1]
  54. ELSE
  55.     %OUT    [PASS2]
  56. ENDIF
  57. ;
  58. PSEG    SEGMENT    PARA
  59.     ASSUME CS:PSEG, DS:PSEG, ES:PSEG, SS:PSEG
  60.     ORG    100H            ;'.COM' FILE
  61. MAIN    PROC    NEAR
  62.     JMP    SHORT BEGIN
  63.     DB    'Copyright (C) 1986, 1987 Richard B. Johnson '
  64. BEGIN:    CLD
  65.     CLI
  66.     MOV    AX,CS
  67.     MOV    DS,AX            ;SEGMENT FIXUPS (MS_DOS SHOULD DO IT)
  68.     MOV    ES,AX
  69.     MOV    SS,AX
  70.     MOV    SP,OFFSET STACK        ;PUT IT WHERE WE CAN KEEP TRACK
  71.     STI
  72.     CALL    CLS            ;CLEAR THE SCREEN
  73.     CALL    SAV_CUR            ;GET CURSOR TYPE
  74.     MOV    WORD PTR [CURSORT],CX    ;SAVE TYPE
  75.     CALL    GET_CMD            ;GET TYPED COMMAND LINE
  76.     CALL    OPENF            ;ATTEMPT TO OPEN THE FILE
  77.     JNC    OPNOK            ;GOOD OPEN
  78.     PUSH    SI            ;SAVE FILENAME
  79.     MOV    SI,OFFSET NOFILE    ;POINT TO 'NO FILE'
  80.     CALL    PNUL            ;PRINT TO SCREEN
  81.     POP    SI            ;RESTORE FILENAME
  82.     CALL    PNUL            ;PRINT TO SCREEN
  83.     MOV    SI,OFFSET CRLF        ;END OF LINE
  84.     CALL    PNUL            ;PRINT TOO
  85.     JMP    FINIS            ;AND EXIT
  86. OPNOK:    MOV    DH,6            ;SEVENTH LINE
  87.     MOV    DL,CNTR
  88.     CALL    POS_CUR            ;SET CURSOR POSITION
  89.     MOV    SI,OFFSET DIAL        ;POINT TO THE SIRING
  90.     CALL    PNUL            ;WRITE TO SCREEN
  91.     INC    DH            ;NEXT LINE
  92.     CALL    POS_CUR            ;SET CURSOR
  93.     MOV    SI,OFFSET DIAL1        ;POINT TO NEXT LINE OF TEXT
  94.     CALL    PNUL            ;PRINT TO SCREEN
  95.     INC    DH            ;READY NEXT LINE
  96.     CALL    POS_CUR            ;SET CURSOR THERE
  97.     MOV    SI,OFFSET DIAL2        ;POINT TO 'RULER'
  98.     CALL    PNUL            ;PRINT TO SCREEN
  99.     MOV    WORD PTR [RULER],DX    ;SAVE THAT LOCATION
  100.     CALL    GET_SIZE        ;GET FILE SIZE
  101.     MOV    DX,WORD PTR [FINAL_H]    ;READY FOR DIVIDE
  102.     MOV    AX,WORD PTR [FINAL_L]    ;GET FINAL NUMBER
  103.     MOV    BX,COL_LEN        ;GET LENGTH OF THE SCALE
  104.     MOV    WORD PTR [RUN_BX],BX    ;GET WRITES TO SCREEN
  105.     DIV    BX            ;AX= NUMBER OF ITERATIONS 
  106.     MOV    WORD PTR [WMASKL],AX    ;SAVE IN MEMORY
  107.     MOV    DX,WORD PTR [RULER]    ;GET 'HOME' LOCATION
  108.     ADD    DH,5            ;FIVE LINES
  109.     CALL    POS_CUR            ;PUT CURSOR THERE
  110.     MOV    SI,OFFSET READY        ;POINT TO 'GET' PLOTTER READY
  111.     CALL    PNUL            ;PRINT TO THE SCREEN
  112. PAUSE:    CALL    KEY            ;WAIT FOR RESPONSE
  113.     JZ    PAUSE            ;CONTUNUE TO LOOP
  114.     CMP    AL,CTL_C        ;SEE IF AN ABORT
  115.     JNZ    GO            ;NOPE
  116.     CALL    CLOSEF            ;YES, CLOSE THE FILE
  117.     MOV    SI,OFFSET ABORTED    ;POINT TO THE STRING
  118.     CALL    PNUL            ;PRINT TO SCREEN
  119.     JMP    FINIS            ;EXIT
  120. GO:    CALL    KILL_CUR        ;KILL THE CURSOR
  121.     MOV    DX,WORD PTR [RULER]    ;GET 'HOME' POSITION
  122.     ADD    DH,5            ;ADD FIVE LINES
  123.     CALL    POS_CUR            ;PUT CURSOR THERE
  124.     MOV    SI,OFFSET WORKING    ;POINT TO THE PROMPT STRING
  125.     CALL    PNUL            ;PRINT TO THE SCREEN
  126. CONT:    CALL    STATUS            ;SHOW OUTPUT BYTE COUNT
  127.     CALL    READF            ;READ THE FILE
  128.     TEST    AX,AX            ;ANY BYTES READ?
  129.     JNZ    OUTPUT            ;YES
  130.     CALL    CLOSEF            ;NO, CLOSE THE FILE
  131.     MOV    SI,OFFSET DONE        ;POINT TO 'END OF FILE'
  132.     CALL    PNUL            ;PRINT TO THE SCREEN
  133.     JMP    FINIS            ;AND EXIT
  134. OUTPUT:    MOV    CX,AX            ;BYTE COUNT
  135.     MOV    SI,OFFSET BUFFER    ;WHERE THE DATA IS
  136.     CALL    COMOUT            ;OUTPUT TO THE SELECTED COM PORT
  137.     JMP    SHORT CONT        ;AND CONTINUE
  138. MAIN    ENDP
  139. ;
  140. ; Get communications port address. BX= index into table.
  141. ; Check to see if adapter is present. Report errors and exit if unavailable.
  142. ;
  143. GET_PORT    PROC    NEAR
  144.     PUSH    DS            ;SAVE DATA SEGMENT
  145.     MOV    AX,BIOS_DATA_SEG    ;WHERE THE BIOS KEEPS ADDRESSES
  146.     MOV    DS,AX            ;FIRST PAGE
  147.     MOV    DX,WORD PTR [BX]    ;GET COM PORT LOCATION
  148.     POP    DS            ;RESTORE SEGMENT
  149.     MOV    WORD PTR [PORT],DX    ;SAVE IN LOCAL AREA
  150.     ADD    DX,2            ;OFFSET TO INTERRUPT IDENT REGIS
  151.     IN    AL,DX            ;GET STATUS
  152.     TEST    AL,11111000B        ;CHECK FOR AN 8250 UART
  153.     JZ    MAYBE            ;COULD BE A REAL UART
  154. NOUART:    MOV    SI,OFFSET BADUART    ;NOT AN 8250 UART
  155.     CALL    PNUL            ;PRINT TO SCREEN
  156.     SHR    BX,1            ;DIVIDE BY TWO (RESTORE BIAS)
  157.     MOV    AL,BL
  158.     ADD    AL,'0'+1        ;RESTORE BIAS
  159.     CALL    CON_OUT            ;OUTPUT THE BYTE
  160.     MOV    SI,OFFSET NFIND        ;POINT TO STRING
  161.     CALL    PNUL            ;PRINT TO SCREEN
  162.     JMP    FINIS            ;EXIT
  163. MAYBE:    ADD    DX,3            ;OFFSET TO LINE STATUS REGISTER
  164.     MOV    CX,-1            ;TEMP TIMER
  165. RESPON:    IN    AL,DX            ;GET UART STATUS
  166.     TEST    AL,THRE            ;SEE IF TX SHIFT REGIS EMPTY
  167.     JNZ    UARTOK            ;YES, PERHAPS A UART AFTER ALL
  168.     LOOP    RESPON            ;WAIT A BIT
  169.     JMP    SHORT NOUART
  170. UARTOK:    RET
  171. GET_PORT    ENDP
  172. ;
  173. ; Print string addressed by SI until a null.
  174. ;
  175. PNUL    PROC    NEAR
  176.     LODSB                ;GET A BYTE
  177.     TEST    AL,AL            ;IS IT A NULL?
  178.     JZ    PDONE            ;YES, DONE
  179.     CALL    CON_OUT            ;NO, SEND IT OUT
  180.     JMP    SHORT PNUL        ;CONTINUE
  181. PDONE:    RET
  182. PNUL    ENDP
  183. ;
  184. ; Parse the command line. Print 'HELP' if command line is not present or isn't
  185. ; correct.
  186. ;
  187. GET_CMD    PROC    NEAR
  188.     MOV    SI,DTA            ;COMMAND LINE BUFFER
  189.     LODSB                ;GET BYTES TYPED
  190.     TEST    AL,AL            ;CHECK FOR NOTHING
  191.     JZ    NOWAY            ;NO COMMAND LINE
  192.     CBW
  193.     MOV    BX,AX            ;NEED AN INDEX REGISTER
  194.     MOV    BYTE PTR [SI+BX],0    ;THIS WILL BE THE END OF FILENAME
  195.     INC    SI            ;GET BY THE SPACE
  196.     LODSB                ;GET PROTOCOL
  197.     AND    AL,95            ;CONVERT TO UPPER CASE
  198.     MOV    BYTE PTR [PROTO],CTS    ;ASSUME CLEAR TO SEND
  199.     CMP    AL,'C'            ;CORRECT?
  200.     JZ    WASOK            ;YES
  201.     MOV    BYTE PTR [PROTO],DSR    ;ASSUME DATA SET READY
  202.     CMP    AL,'D'            ;CORRECT?
  203.     JZ    WASOK            ;YES
  204.     MOV    BYTE PTR [PROTO],0FFH    ;ASSUME X-ON/X-OFF
  205.     CMP    AL,'X'            ;IS IT XON/XOFF?
  206.     JZ    WASOK            ;YES
  207. NOWAY:    MOV    SI,OFFSET HELP        ;NONE OF ABOVE, PRINT HELP
  208.     CALL    PNUL            ;PRINT TO SCREEN
  209.     JMP    FINIS            ;EXIT
  210. WASOK:    LODSB                ;GET NEXT BYTE
  211.     MOV    CX,BX            ;SAVE INDEX
  212.     XOR    BX,BX            ;ASSUME COM PORT 1
  213.     CMP    AL,' '            ;WAS IT A SPACE?
  214.     JZ    USE1            ;WAS JUST A SPACE
  215.     SUB    AL,'0'+1        ;SUBTRACT ASCII BIAS
  216.     JC    NOWAY            ;NOT A CORRECT PORT NUMBER
  217.     CMP    AL,5            ;FOUR PORTS MAX
  218.     JNC    NOWAY            ;TOO HIGH A PORT NUMBER
  219.     MOV    BL,AL            ;USE AS AN INDEX
  220.     INC    SI            ;FILENAME FOLLOWS
  221. USE1:    MOV    WORD PTR [FNAME],SI    ;SAVE FILENAME ADDRESS
  222.     ADD    BX,BX            ;TIMES TWO
  223.     CALL    GET_PORT
  224.     MOV    BX,CX            ;RESTORE INDEX
  225.     RET
  226. GET_CMD    ENDP
  227. ;
  228. ; Output the buffer contents addressed by SI to the communications port
  229. ; respecting the various protocols.
  230. ;
  231. COMOUT    PROC    NEAR
  232.     CMP    BYTE PTR [PROTO],0FFH    ;SEE IF X-ON/X-OFF
  233.     JZ    XON
  234. AGAIN:    CALL    CHECK            ;CHECK FOR AN ABORT
  235.     CALL    MOD_STAT        ;GET MODEM STATUS
  236.     TEST    AL,BYTE PTR [PROTO]    ;SEE IF OK TO TRANSMIT
  237.     JNZ    NOWAIT            ;YES, IT'S OK
  238.     PUSH    CX            ;SAVE COUNT
  239.     CALL    SAV_CUR            ;SAVE CURSOR POSITION
  240.     PUSH    SI            ;SAVE LOCATION
  241.     MOV    SI,OFFSET SYNC        ;POINT TO STRING
  242.     MOV    WORD PTR [LSPRP],SI    ;SAVE FOR NOW
  243.     CALL    PNUL            ;PRINT ON THE SCREEN
  244.     POP    SI            ;RESTORE LOCATION
  245.     CALL    RES_CURP        ;RESTORE CURSOR POSITION
  246. NOTYET:    CALL    CHECK            ;CHECK FOR AN ABORT
  247.     CALL    MOD_STAT
  248.     TEST    AL,BYTE PTR [PROTO]    ;SEE IF IT'S OK YET
  249.     JZ    NOTYET            ;NOT YET
  250.     CALL    SAV_CUR            ;SAVE CURSOR
  251.     PUSH    SI            ;SAVE LOCATION
  252.     MOV    SI,OFFSET RESUME    ;POINT TO THE STRING
  253.     MOV    WORD PTR [LSPRP],SI    ;SAVE FOR NOW
  254.     CALL    PNUL            ;PRINT TO SCREEN
  255.     POP    SI            ;RESTORE LOCATION
  256.     CALL    RES_CURP        ;RESTORE CURSOR POSITION
  257.     POP    CX            ;RESTORE COUNT
  258.     JMP    SHORT NOWAIT        ;OK TO CONTINUE
  259. ;
  260. XON:    CALL    CHECK            ;CHECK WAIT/ABORT FROM CONSOLE
  261.     CALL    COMIN            ;CHECK INPUT PORT
  262.     JZ    NOWAIT            ;NOTHING HERE YET
  263.     CMP    AL,X_OFF        ;WANT TO WAIT
  264.     JNZ    NOWAIT            ;NOPE, MUST BE GARBAGE
  265.     CALL    WAITX            ;YES, WAIT FOR X_ON
  266. NOWAIT:    CALL    BYTOUT            ;OUTPUT THE BYTE
  267.     LOOP    COMOUT            ;CONTINUE
  268.     RET
  269. COMOUT    ENDP
  270. ;
  271. ; Get any possible byte from the 'COM' port.
  272. ;
  273. COMIN    PROC    NEAR
  274.     MOV    DX,WORD PTR [PORT]    ;GET COM PORT ADDRESS
  275.     PUSH    DX            ;SAVE FOR NOW
  276.     ADD    DX,LSTAT        ;ADD IN OFFSET TO LINE STATUS
  277.     IN    AL,DX            ;GET STATUS BYTE
  278.     POP    DX            ;RESTORE BASE PORT ADDRESS
  279.     TEST    AL,DR            ;SEE IF DATA READY
  280.     JZ    NODAT            ;WAIT FOREVER UNTIL READY
  281.     IN    AL,DX            ;GET BYTE
  282.     INC    DX            ;MAKE CERTAIN NO ZERO
  283. NODAT:    RET
  284. COMIN    ENDP
  285. ;
  286. ; Check the modem status of the UART.
  287. ;
  288. MOD_STAT    PROC    NEAR
  289.     MOV    DX,WORD PTR [PORT]    ;GET PORT ADDRESS
  290.     ADD    DX,MSTAT        ;ADD IN OFFSET TO MODEM STATUS
  291.     IN    AL,DX            ;GET STATUS BYTE
  292.     RET
  293. MOD_STAT    ENDP
  294. ;
  295. ; Output a byte from the buffer addressed by SI to the 'COM1' UART.
  296. ;
  297. BYTOUT    PROC    NEAR
  298.     MOV    DX,WORD PTR [PORT]    ;GET COM PORT ADDRESS
  299.     PUSH    DX            ;SAVE FOR NOW
  300.     ADD    DX,LSTAT        ;ADD IN OFFSET TO LINE STATUS
  301. FOREVER:
  302.     IN    AL,DX            ;GET STATUS BYTE
  303.     TEST    AL,THRE            ;WAIT FOR HOLDING REGISTER EMPTY
  304.     JNZ    EMPTY            ;WAIT UNTIL READY
  305.     CALL    STATUS            ;UART NOT READY, SHOW STATUS
  306.     JMP    SHORT FOREVER        ;CONTINUE
  307. EMPTY:    POP    DX            ;RESTORE BASE PORT ADDRESS
  308.     LODSB                ;GET BYTE FROM BUFFER
  309.     OUT    DX,AL            ;AND OUTPUT THE BYTE
  310.     INC    WORD PTR [XMITL]    ;UP THE BYTE COUNT
  311.     JNZ    BYPASS            ;NO OVERFLOW
  312.     INC    WORD PTR [XMITH]    ;UPDATE THE COUNT
  313. BYPASS:    CALL    SCALE
  314.     RET
  315. BYTOUT    ENDP
  316. ;
  317. ; Wait for the host to send a X-ON. Abort from the keyboard is possible.
  318. ;
  319. WAITX    PROC    NEAR            ;WAIT FOR X-ON FROM HOST
  320.     PUSH    SI            ;SAVE LOCATION
  321.     PUSH    CX            ;SAVE COUNT
  322.     CALL    SAV_CUR            ;SAVE CURSOR POSITION
  323.     MOV    SI,OFFSET SYNC        ;POINT TO STRING
  324.     MOV    WORD PTR [LSPRP],SI    ;SAVE FOR NOW
  325.     CALL    PNUL            ;PRINT TO SCREEN
  326.     CALL    RES_CURP        ;RESTORE CURSOR POSITION
  327. WAIT0:    CALL    CHECK            ;CHECK FOR ABORT
  328.     CALL    COMIN            ;GET INPUT BYTE
  329.     CMP    AL,X_ON            ;READY TO RESUME?
  330.     JNZ    WAIT0            ;NOPE
  331.     CALL    SAV_CUR            ;SAVE CURSOR POSITION
  332.     MOV    SI,OFFSET RESUME    ;POINT TO STRING
  333.     MOV    WORD PTR [LSPRP],SI    ;SAVE FOR NOW
  334.     CALL    PNUL            ;PRINT TO SCREEN
  335.     CALL    RES_CURP        ;RESTORE THE CURSOR POSITION
  336.     POP    CX            ;RESTORE COUNT
  337.     POP    SI            ;RESTORE LOCATION
  338.     RET
  339. WAITX    ENDP
  340. ;
  341. ; Check for a possible abort from the keyboard. Pause for a second key
  342. ; pressed if there is any keyboard input.
  343. ;
  344. CHECK    PROC    NEAR
  345.     PUSH    SI            ;SAVE LOCATION
  346.     PUSH    CX            ;SAVE COUNT
  347.     CALL    KEY            ;CHECK FOR A KEY PRESSED
  348.     JZ    NOKEY            ;NO KEY WAS PRESSED
  349.     CMP    AL,CTL_C        ;CHECK FOR CONTROL C
  350.     JZ    QUIT            ;WAS CONTROL C
  351.     CALL    SAV_CUR            ;SAVE CURRENT CURSOR POSITION
  352.     MOV    SI,OFFSET HOLDING    ;POINT TO STRING
  353.     CALL    PNUL            ;PRINT IT
  354.     CALL    RES_CURP        ;RESTORE THE CURSOR POSITION
  355. HOLD    PROC    NEAR            ;WAIT FOR A KEY TO BE PRESSED
  356.     CALL    KEY            ;CHECK KEYBOARD
  357.     JZ    HOLD            ;NOTHING PRESSED
  358.     CMP    AL,CTL_C        ;CHECK FOR CONTROL C
  359.     JZ    QUIT            ;ABORT
  360.     MOV    SI,WORD PTR [LSPRP]    ;GET LAST STRING
  361.     CALL    PNUL            ;PRINT IT
  362.     CALL    RES_CURP        ;RESTORE CURSOR POSITION
  363. NOKEY:    POP    CX            ;RESTORE COUNT
  364.     POP    SI            ;RESTORE LOCATION
  365.     RET                ;END OF HOLD
  366. QUIT:    POP    CX            ;LEVEL STACK CX=COUNT
  367.     POP    SI            ;BUFFER LOCATION
  368.     POP    AX            ;RETURN ADDRESS
  369.     MOV    SI,OFFSET ABORTED
  370.     CALL    PNUL
  371.     JMP    FINIS
  372. HOLD    ENDP
  373. CHECK    ENDP
  374. ;
  375. ; Get any input from the keyboard.
  376. ;
  377. KEY    PROC    NEAR
  378.     MOV    AH,1            ;CHECK IF CHARACTER WAITING
  379.     INT    KBD
  380.     JZ    NOPE            ;NOTHING HERE
  381.     MOV    AH,0            ;YES, GET THE CHARACTER
  382.     INT    KBD
  383.     TEST    AX,AX            ;INSURE NO ZERO FLAG
  384. NOPE:    RET
  385. KEY    ENDP
  386. ;
  387. ; Print transmit status to the screen.
  388. ;
  389. STATUS    PROC    NEAR
  390.     PUSH    SI            ;SAVE INDEX, DESTROYED BY ASCII
  391.     PUSH    DX            ;SAVE ALSO
  392.     PUSH    CX
  393.     CALL    SAV_CUR
  394.     MOV    DX,WORD PTR [XMITH]    ;GET HIGH WORD OF BYTES TRANSMITTED
  395.     MOV    AX,WORD PTR [XMITL]    ;GET LOW WORD OF BYTES TRANSMITTED
  396.     CALL    ASCII
  397.     CALL    RES_CURP        ;RESTORE CURSOR POSITION
  398.     POP    CX
  399.     POP    DX
  400.     POP    SI
  401.     RET
  402. STATUS    ENDP
  403. ;
  404. ; Open the file pointed to by [FNAME]
  405. ;
  406. OPENF    PROC    NEAR
  407.     MOV    DX,WORD PTR [FNAME]    ;POINT TO FILENAME
  408.     XOR    CX,CX            ;NORMAL FILE
  409.     MOV    AX,3D00H        ;OPEN FOR READING
  410.     INT    MS_DOS
  411.     MOV    WORD PTR [HANDLE],AX    ;SAVE THE HANDLE
  412.     JNC    FOUND            ;FILE WAS FOUND
  413.     MOV    BYTE PTR [SI+BX-2],0    ;FOR A BAD FILENAME
  414.     RET
  415. FOUND:    MOV    AH,4EH            ;GET FILE CHARACTERISTICS
  416.     INT    MS_DOS            ;WILL RETURN IN DTA [80H]
  417.     RET
  418. OPENF    ENDP
  419. ;
  420. ; Close the file.
  421. ;
  422. CLOSEF    PROC    NEAR
  423.     MOV    AX,3E00H        ;CLOSE FILE FUNCTION
  424.     MOV    BX,WORD PTR [HANDLE]    ;GET THE FILE HANDLE
  425.     INT    MS_DOS
  426.     RET
  427. CLOSEF    ENDP
  428. ;
  429. ; Read the file. Read as much into memory as possible within the 64k
  430. ; segment allowed to speed file access. For most files, only one read
  431. ; will be required.
  432. ;
  433. READF    PROC    NEAR
  434.     MOV    DX,OFFSET BUFFER    ;WHERE TO PUT FILE DATA
  435.     MOV    CX,-1            ;64 K TO READ
  436.     SUB    CX,DX            ;MINUS SPACE USED FOR PROGRAM
  437.     MOV    BX,WORD PTR [HANDLE]    ;GET FILE HANDLE
  438.     MOV    AX,3F00H        ;READ THE FILE
  439.     INT    MS_DOS
  440.     RET
  441. READF    ENDP
  442. ;
  443. ; End the program, return to MS_DOS. Return status OK even if aborted.
  444. ;
  445. FINIS    PROC    NEAR
  446.     CALL    RES_CUR            ;RESTORE CURSOR TYPE
  447.     MOV    DH,23            ;24TH LINE
  448.     MOV    DL,0            ;FIRST COLUMN
  449.     CALL    POS_CUR            ;CURSOR AT BOTTOM OF SCREEN
  450.     MOV    AX,4C00H
  451.     INT    MS_DOS
  452. FINIS    ENDP
  453. ;
  454. GET_SIZE    PROC    NEAR
  455.     MOV    DX,WORD PTR [RULER]
  456.     ADD    DH,2            ;TWO LINES
  457.     CALL    POS_CUR            ;PUT CURSOR THERE
  458.     MOV    SI,OFFSET HOWBIG
  459.     CALL    PNUL
  460.     MOV    SI,DTA + NAMEF        ;POINT TO THE FILENAME
  461.     CALL    PNUL
  462.     MOV    SI,OFFSET IS
  463.     CALL    PNUL
  464.     MOV    SI,DTA
  465.     MOV    DX,WORD PTR [SI+ SIZEH]    ;GET PART OF FILE SIZE
  466.     MOV    AX,WORD PTR [SI+ SIZEL]    ;GET LOW PART OF FILE SIZE
  467.     MOV    WORD PTR [FINAL_L],AX
  468.     MOV    WORD PTR [FINAL_H],DX
  469.     CALL    ASCII
  470.     MOV    SI,OFFSET LONG
  471.     CALL    PNUL
  472.     RET
  473. GET_SIZE    ENDP
  474. ;
  475. ; Print double precision number in DX:AX
  476. ;
  477. ASCII    PROC    NEAR
  478.     MOV    SI,0000            ;LEADING ZERO FLAG
  479.     MOV    CX,3B9AH        ;GET BILLIONS
  480.     MOV    BX,0CA00H
  481.     CALL    SUBTR            ;SUBTRACT THEM OUT
  482.     CALL    COMMA            ;PUT IN A COMMA
  483.     MOV    CX,05F5H        ;GET HUNDRED-MILLIONS
  484.     MOV    BX,0E100H
  485.     CALL    SUBTR            ;SUBTRACT THEM OUT
  486.     MOV    CX,0098H        ;GET TEN-MILLIONS
  487.     MOV    BX,9680H
  488.     CALL    SUBTR            ;SUBTRACT THEM OUT
  489.     MOV    CX,000FH        ;GET MILLIONS
  490.     MOV    BX,4240H
  491.     CALL    SUBTR            ;SUBTRACT THEM OUT
  492.     CALL    COMMA            ;PUT IN A COMMA
  493.     MOV    CX,0001H        ;GET HUNDRED-THOUSANDS
  494.     MOV    BX,86A0H
  495.     CALL    SUBTR            ;SUNTRACT THEM OUT
  496.     MOV    CX,0000H        ;GET TEN-THOUSANDS
  497.     MOV    BX,2710H
  498.     CALL    SUBTR            ;SUBTRACT THEM OUT
  499.     MOV    CX,0000H        ;GET THOUSANDS
  500.     MOV    BX,03E8H
  501.     CALL    SUBTR            ;SUNTRACT THEM OUT
  502.     CALL    COMMA            ;PUT IN A COMMA
  503.     MOV    CX,0000H        ;GET HUNDREDS
  504.     MOV    BX,0064H
  505.     CALL    SUBTR            ;SUBTRACT THEM OUT
  506.     MOV    CX,0000H        ;GET TENS
  507.     MOV    BX,000AH
  508.     CALL    SUBTR            ;SUBTRACT THEM OUT
  509.     ADD    AL,'0'
  510.     JMP    SHORT CON_OUT        ;IMPLIED RETURN
  511. ;
  512. SUBTR:     MOV     DI,'0'-1        ;START WITH ONE LESS THAN ASCII BIAS
  513. SUBTR1:     INC     DI            ;COUNTER
  514.      SUB     AX,BX            ;DWORD SUBTRACTION
  515.      SBB     DX,CX
  516.      JNB     SUBTR1            ;CONTINUE UNTIL CARRY
  517.      ADD     AX,BX            ;ONE TOO MANY, ADD BACK
  518.      ADC     DX,CX
  519.      PUSH     AX            ;SAVE FOR NOW
  520.      MOV     AX,DI            ;GET COUNT
  521.      CMP     SI,0            ;SEE IF ANY BYTES HAVE BEEN PRINTED
  522.      JNZ     SUBTR2            ;NO, CAN'T BE A LEADING ZERO
  523.      CMP     AL,'0'            ;IS IS A ZERO?
  524.      JZ     SUBTR3            ;YES, DON'T PRINT LEADING ZEROS
  525.      INC     SI            ;NO SET FLAG
  526. SUBTR2:     CALL     CON_OUT
  527. SUBTR3:     POP     AX
  528.      RET
  529. ;
  530. COMMA:    CMP    SI,0            ;SEE IF ANY BYTES HAVE BEEN PRINTED
  531.     JZ    PASS            ;NO, THEN NO COMMAS
  532.     PUSH    AX
  533.     MOV    AL,','
  534.     CALL    CON_OUT
  535.     POP    AX
  536. PASS:    RET
  537. ASCII    ENDP
  538. ;
  539. ; Using the 'faster than DOS' video ROM routine, output a byte to the screen.
  540. ;
  541. CON_OUT    PROC    NEAR
  542.     PUSH    BX
  543.     PUSH    DX
  544. ZERO:    MOV    AH,14            ;WRITE CHARACTER TO SCREEN,
  545.     MOV    BX,7            ;NORMAL ATTRIBUTE
  546.     INT    VID_ROM
  547. EXIT:    POP    DX
  548.     POP    BX
  549.     RET
  550. CON_OUT    ENDP
  551. ;
  552. SAV_CUR    PROC    NEAR
  553.     MOV    AH,3            ;GET CURSOR POSITION, TYPE
  554.     MOV    BH,0            ;PAGE ZERO
  555.     INT    VID_ROM
  556.     MOV    WORD PTR [CURSORP],DX    ;SAVE POSITION
  557.     RET
  558. SAV_CUR    ENDP
  559. ;
  560. ; Kill the cursor by making it so tiny you can't see it!!
  561. ;
  562. KILL_CUR    PROC    NEAR
  563.     MOV    CX,-1
  564.     MOV    AH,1
  565.     INT    VID_ROM
  566.     RET
  567. KILL_CUR    ENDP
  568. ;
  569. RES_CUR    PROC    NEAR
  570.     MOV    AH,1
  571.     MOV    CX,WORD PTR [CURSORT]    ;GET OLD CURSOR TYPE
  572.     INT    VID_ROM            ;RESTORE THE CURSOR
  573.     RET
  574. RES_CUR    ENDP
  575. ;
  576. RES_CURP    PROC    NEAR
  577.     MOV    DX,WORD PTR [CURSORP]    ;GET OLD CURSOR POSITION
  578. ;
  579. POS_CUR    PROC    NEAR            ;PUT CURSOR AT DH=ROW, DL=COLUMN
  580.     MOV    AH,2
  581.     MOV    BH,0            ;PAGE ZERO
  582.     INT    VID_ROM
  583.     RET
  584. POS_CUR    ENDP
  585. RES_CURP    ENDP
  586. ;
  587. ADVANCE    PROC    NEAR
  588.     CALL    SAV_CUR            ;SAVE PRESENT POSITION
  589.     MOV    DX,WORD PTR [RULER]    ;GET LAST 'RULER' POSITION
  590.     INC    WORD PTR [RULER]    ;READY NEXT
  591.     CALL    POS_CUR            ;PUT CURSOR AT LAST CHARACTER POS
  592.     MOV    AL,'='            ;COVER UP THE '>'
  593.     CALL    CON_OUT            ;WRITE TO SCREEN
  594.     MOV    AL,'>'            ;ADD AN ARROW
  595.     CALL    CON_OUT            ;WRITE TO SCREEN
  596.     CALL    RES_CURP        ;RESTORE CURSOR
  597.     RET
  598. ADVANCE    ENDP
  599. ;
  600. SCALE    PROC    NEAR
  601.     PUSH    CX            ;SAVE COUNT
  602.     DEC    WORD PTR [RUN_BX]
  603.     JNZ    NOADV
  604.     MOV    AX,WORD PTR [WMASKL]    ;GET NEW PARAMS
  605.     MOV    WORD PTR [RUN_BX],AX    ;INTO THE 'INSIDE' RUNNING COUNT
  606.     CALL    ADVANCE            ;ADVANCE THE POINTER
  607. NOADV:    POP    CX            ;RESTORE BYTE COUNT
  608.     RET
  609. SCALE    ENDP
  610. ;
  611. CLS    PROC    NEAR
  612.     MOV    AX,0500H        ;SELECT ACTIVE PAGE
  613.     INT    VID_ROM
  614.     MOV    AX,0600H        ;SCROLL ACTIVE PAGE AWAY
  615.     XOR    CX,CX            ;UPPER LEFT
  616.     MOV    BH,7            ;ATTRIBUTE
  617.     MOV    DH,24            ;25TH ROW
  618.     MOV    DL,79            ;80TH COLUMN
  619.     INT    VID_ROM
  620.     MOV    DH,1            ;SECOND LINE LINE FROM TOP
  621.     MOV    DL,CENTER        ;WHATEVER CENTERS THE STRING
  622.     CALL    POS_CUR            ;CURSOR HOME
  623.     MOV    SI,OFFSET LOGO        ;POINT TO SIGNON
  624.     CALL    PNUL            ;PRINT TO THE SCREEN
  625.     MOV    DX,0500H        ;SIXTH LINE FROM TOP
  626.     CALL    POS_CUR            ;CURSOR HOME
  627.     RET
  628. CLS    ENDP
  629. ;
  630. ; Data area.
  631. ;
  632. PROTO    DB    ?        ;MASK BYTE FOR PROTOCOL
  633. EVEN
  634. HANDLE    DW    ?        ;OPEN FILE HANDLE
  635. FNAME    DW    ?        ;LOCATION OF THE FILENAME
  636. CURSORT    DW    ?        ;SAVE CURSOR TYPE
  637. CURSORP    DW    ?        ;SAVE CURSOR POSITION
  638. PORT    DW    ?        ;COM PORT
  639. XMITH    DW    0        ;NUMBER OF BYTES TRANSMITTED (HIGH WORD)
  640. XMITL    DW    0        ;NUMBER OF BYTES TRANSMITTED (LOW WORD)
  641. LSPRP    DW    RESUME        ;LAST STATUS WORD
  642. FINAL_L    DW    ?        ;FINAL NUMBER
  643. FINAL_H    DW    ?
  644. RUN_BX    DW    ?
  645. WMASKL    DW    ?
  646. CURSOR    DW    ?        ;SAVE CURSOR
  647. RULER    DW    ?
  648. ;
  649. DONE    DB    CR,LF,'         The plot is finished.',CR,LF,BEL,0
  650. ABORTED    DB    CR,LF,'         Aborted!  ',CR,LF,BEL,0
  651. HOLDING    DB    CR,LF,'         [Holding] ',0
  652. RESUME    DB    CR,LF,'                   ',0
  653. SYNC    DB    CR,LF,'         [TTYSYNC]',0
  654.     DB    16 DUP ('STACK   ')
  655. STACK    LABEL    WORD
  656. ;
  657. ; From here on up to offset 64k is used for the file buffer. The data
  658. ; is overwritten since it's only used before the file is read into the
  659. ; buffer.
  660. ;
  661. BUFFER    LABEL    BYTE
  662. DIAL    DB    '                      Percent completion',0
  663. DIAL1    DB    '0     10    20    30    40    50    60    '
  664.     DB    '70    80    90   100',0
  665. DIAL2    DB    10 DUP ("+-----")
  666.     DB    "+"
  667.     DB    0
  668. CNTR    EQU    (40 - ($ - DIAL2)/2)
  669. LOGO    DB    'uDESIGNS IBM/PC/XT Plotter Driver',0
  670. CENTER    EQU    (40 - ($ - LOGO)/2)
  671. HOWBIG    DB    'The plot file ',0
  672. IS    DB    ' is ',0
  673. LONG    DB    ' bytes in length.'
  674. CRLF    DB    CR,LF,0
  675. READY    DB    'Hit any key when the plotter is ready: ',0
  676. WORKING    DB    '                                        '
  677.     DB    CR,LF,'         Hit any key to pause.'
  678.     DB    CR,LF,'         Hit any key to resume.'
  679.     DB    CR,LF,'         Hit ^C to abort.'
  680.     DB    CR,LF,'         Bytes transmitted: ',0
  681. BADUART    DB    CR,LF,'         Communications adapter COM',0
  682. NFIND    DB    ': not present.'
  683.     DB    CR,LF,0
  684. NOFILE    DB    CR,LF,'         File not found: ',0
  685. HELP    DB    CR,LF,'FASTPLOT [C,D,X]<PORT> [FILENAME]'
  686.     DB    CR,LF,'C = CLEAR TO SEND protocol  (pin  4 of DB25 connector)'
  687.     DB    CR,LF,'D = DATASET READY protocol  (pin 20 of DB25 connector)'
  688.     DB    CR,LF,'X = X-ON/X-OFF protocol'
  689.     DB    CR,LF,'PORT<OPTIONAL> = 1, 2, 3, 4 (Default is COM1:)'
  690.     DB    CR,LF,'FILENAME = any \PATH\FILENAME combination.'
  691.     DB    CR,LF,'Examples:'
  692.     DB    CR,LF,'Fastplot x orcad.plt'
  693.     DB    CR,LF,'Fastplot x2 orcad.plt'
  694.     DB    CR,LF,'Fastplot c2 orcad.plt'
  695.     DB    CR,LF,'Fastplot d4 c:\draft\orcad.plt'
  696.     DB    CR,LF,0
  697. PSEG    ENDS
  698.     END    MAIN
  699.